<template>
  <div class="y-h-full">
    <el-table ref="innerTableRef" :data="tableData" border v-on="$listeners"
      @select="handleSelectChange" @select-all="handleSelectAllChange" size="small" :row-key="rowKey" v-bind="$attrs" height="100%"
      class="y-w-full">
      <slot name="before-table" />
      <el-table-column v-for="col in tableColumn" :key="col.prop" :prop="col.prop" :label="col.label" :width="col.width"
        :minWidth="col.minWidth || comMinWidth(col)" :sortable="col.sortable" header-align="center"
        :align="col.align || 'center'" show-overflow-tooltip
        :class-name="col.img || col.tag ? 'yy-table-hidden-text' : col.className" v-bind="col.bindConfig || {}">
        <template slot="header">
          {{ col.label }}
          <el-tooltip v-if="col.tips" effect="dark" :content="col.tips" placement="bottom">
            <span class="el-icon-question y-text-sm sm:y-text-md y-cursor-help"></span>
          </el-tooltip>
        </template>
        <template slot-scope="{ row, $index }">
          <!-- 插槽 -->
          <slot v-if="col.slotName" :name="col.slotName" :row="row" :index="$index" />
          <!-- 标签 -->
          <el-tag v-else-if="col.tag" :type="filterTag('type', row, col)"
            class="!y-px-0 !y-w-full lg:!y-w-auto lg:!y-px-3" disable-transitions>{{ filterTag('label', row,
            col)}}</el-tag>
          <!-- 时间 -->
          <template v-else-if="col.time">
            {{ row[col.prop] | formatterTime(col.format) }}
          </template>
          <!-- 图标 -->
          <i v-else-if="col.icon" :class="row[col.prop]" :title="row[col.prop]"
            class="y-text-base !y-px-0 !y-w-full lg:!y-w-auto lg:!y-px-3"></i>
          <!-- 图片 -->
          <template v-else-if="col.img">
            <el-avatar v-if="col.avatar" size="medium" :src="row[col.prop]"
              :icon="!row[col.prop] ? 'el-icon-user-solid' : ''">{{ row[col.avatarAlias] || '' }}</el-avatar>
            <el-image class="!y-px-0 !y-w-full md:y-max-w-24 md:!y-px-3"
              :preview-src-list="row[col.prop] ? [row[col.prop]] : []" v-else :src="row[col.prop]"
              :fit="col.fit"></el-image>
          </template>
          <!-- 默认 -->
          <template v-else>{{ col.formatter ? col.formatter(row) : row[col.prop] }}</template>
        </template>
      </el-table-column>
      <slot name="after-table" />
    </el-table>
  </div>
</template>

<script>
import dayjs from "dayjs";
import resize from "@/mixins/resize";
export default {
  name: "yyTable",
  mixins: [resize],
  props: {
    tableData: {
      type: Array,
      default: () => [],
    },
    tableColumn: {
      type: Array,
      default: () => [],
    },
    rowKey: {
      type: [String, Function],
      default: 'id'
    },
  },
  data() {
    return {
      crossPageMap: new Map(),
    };
  },
  filters: {
    formatterTime (time, format) {
      if (!time) return;
      return dayjs(new Date(time)).format(format || 'YYYY-MM-DD');
    }
  },
  methods: {
    filterTag(type, row, col) {
      if (!col.tagOptions || !col.tagOptions.length)
        return String(row[col.prop]);
      const res = col.tagOptions.filter((c) => c.value == row[col.prop])[0];
      if (!res) return String(row[col.prop]);
      if (type === "type") return res.tagType;
      return res.label;
    },
    comMinWidth(col) {
      const labelLength = col.label ? col.label.length : 4;
      return (labelLength + (col.tips ? 0.25 : 0)) * 28;
    },
    onResize() {
      this.doLayout();
    },
    doLayout() {
      const ref = this.$refs.innerTableRef;
      if (ref && ref.$refs && ref.$refs.bodyWrapper) {
        ref.$refs.bodyWrapper.style.height = 0;
      }
      this.timer && clearTimeout(this.timer);
      this.timer = setTimeout(() => {
        ref.$refs.bodyWrapper.style.height =
          ref.$el.offsetHeight - ref.$refs.headerWrapper.offsetHeight + "px";
        this.$nextTick(() => {
          if (ref && ref.doLayout) {
            ref.doLayout();
          }
        });
      }, 300);
    },
    /**
     * 设置默认选中的row-key对象数组
     * @param rowKeyObjArr 
     */
    setDefaultCorssPageMap (rowKeyObjArr) {
      if (rowKeyObjArr && rowKeyObjArr.length) {
        rowKeyObjArr.forEach(c => {
          this.crossPageMap.set(c[this.rowKey], c);
        })
      }
    },
    handleSelectChange (_, row) {
      const checked = this.crossPageMap.has(row[this.rowKey])
      if (checked) {
        this.crossPageMap.delete(row[this.rowKey])
      } else {
        this.crossPageMap.set(row[this.rowKey], row)
      }
    },
    handleSelectAllChange (val) {
      this.tableData.forEach(row => {
        const isChecked = this.crossPageMap.has(row[this.rowKey])
        if (val.length === 0) {
          // 取消全选 只有选中的需要改变状态
          if (isChecked) this.crossPageMap.delete(row[this.rowKey])
        } else {
          // 全选
          //  因为有reserve-selection 所以会返回其他页的数据 如果val里面没有当前页的数据 就删除 如果没有reserve-selection 则不需要这行循环的代码
          // reserve-selection 可以让分页的全选按钮保留半选状态
          if(val.findIndex(ele => ele[this.rowKey] == row[this.rowKey]) == -1){
            this.crossPageMap.delete(row[this.rowKey])
          }
          //如果没有选中就添加
          if (!isChecked) this.crossPageMap.set(row[this.rowKey],row)
        }
      })
    },
    clearSelection () {
      this.$refs.innerTableRef.clearSelection();
      this.crossPageMap = new Map();
    },
    restoreSelections () {
      this.tableData.forEach(row => {
        const checked = this.crossPageMap.has(row[this.rowKey])
        if (checked) this.$refs.innerTableRef?.toggleRowSelection(row, true)
      })
    },
  },
  activated() {
    this.doLayout();
  },
};
</script>

<style lang="scss" scoped>
::v-deep {
  .yy-table-hidden-text {
    .cell {
      text-overflow: initial;
    }
  }
}
</style>